
function virtualList(pros) {
    // 当前组
    this.nowItem = 0;
    // 项数组
    this.itemArr = [];

    // 虚拟列表 dom
    this.virtualList = document.querySelector(pros.virtualList);
    if(!this.virtualList)
        return false;
    // 列表窗口 dom
    this.listWindow = this.virtualList.querySelector(".listWindow");
    // 列表 dom
    this.list = this.virtualList.querySelector(".list");
    // 项创建函数
    this.itemCreator = pros.itemCreator;
    if(!this.listWindow || !this.list || !this.itemCreator)
        return false;

    // 预载入数量
    this.preLoadItemNum = pros.preLoadItemNum || 5;

    // 初始化
    this.init();

    // 添加监听
    this.listWindow.addEventListener("scroll", (event) => {
        this.itemHeight = this.list.firstElementChild.offsetHeight;
        let halfNum = Math.floor(this.preLoadItemNum / 2);
        this.bottomScrollListener(event.target.scrollTop, halfNum);
        this.topScrollListener(event.target.scrollTop, halfNum);
    });
}

// 后滚观察
virtualList.prototype.bottomScrollListener = function(disTop, halfNum) {
    if(disTop + this.listWindow.clientHeight < (this.nowItem + 1) * this.itemHeight)
        return;
    this.nowItem += 1;
    // 检测是否已加载
    if(!this.itemArr[this.nowItem + halfNum]) {
        let fragment = this.createItem(this.nowItem + halfNum);
        this.itemArr.push(fragment);
    }
    let fragment = this.itemArr[this.nowItem + halfNum];
    this.list.appendChild(fragment);

    if(this.list.childElementCount <= this.preLoadItemNum)
        return;
    this.list.removeChild(this.list.firstElementChild);
    this.list.style.paddingTop = `${(this.nowItem - halfNum) * this.itemHeight}px`;
}

// 前滚观察
virtualList.prototype.topScrollListener = function(disTop, halfNum) {
    if(disTop + this.listWindow.clientHeight > (this.nowItem) * this.itemHeight)
        return;
    this.nowItem -= 1;
    this.list.removeChild(this.list.lastElementChild);

    // 检测是否越界
    if(!this.itemArr[this.nowItem - halfNum])
        return;
    let fragment = this.itemArr[this.nowItem - halfNum];
    this.list.insertBefore(fragment, this.list.firstElementChild);
    this.list.style.paddingTop = `${(this.nowItem - halfNum) * this.itemHeight}px`;
}

// 项目创建函数
virtualList.prototype.createItem = function(index) {
    let fragment = document.createDocumentFragment();
    // 项目
    let item = document.createElement("div");
    // 编号
    item.className = `item_${index}`;
    // 创建并插入模板
    item.innerHTML = this.itemCreator(index);

    fragment.appendChild(item);
    return item;
}

// 虚拟列表初始化
virtualList.prototype.init = function() {
    // 生成预加载
    let halfNum = Math.ceil(this.preLoadItemNum / 2);
    for(let i = 0; i < halfNum; i++) {
        let fragment = this.createItem(i);
        this.itemArr.push(fragment);
        this.list.appendChild(fragment);
    }
}

function createVirtuallList(pros) {
    return new virtualList(pros || null);
}



function testItemCreate(index) {
    index;
    let templet = ``;
    for(let i = 0; i < 30; i++) {
        templet += `
            <div class="numberBox">
                ${String(i).padStart(2, "0")}
            </div>
        `;
    }
    return templet;
}

var test = createVirtuallList({
    virtualList: ".virtualList",
    preLoadItemNum: 5,
    itemCreator: testItemCreate,
});
console.log(test);